package com.daxue.localserver.interceptor;

import io.grpc.ForwardingServerCall;
import io.grpc.Metadata;
import io.grpc.MethodDescriptor;
import io.grpc.ServerCall;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.Status;
import lombok.extern.slf4j.Slf4j;

/**
 * @author daxue0929
 * @date 2022/08/31
 **/
@Slf4j
public class LogGrpcInterceptor implements ServerInterceptor {

    // 链路追踪参数traceId
    private static final Metadata.Key<String> TRACE = Metadata.Key.of("traceId", Metadata.ASCII_STRING_MARSHALLER);

    // 链路追踪参数spanId
    private static final Metadata.Key<String> SPAN = Metadata.Key.of("spanId", Metadata.ASCII_STRING_MARSHALLER);

    // 链路追踪参数parentId
    private static final Metadata.Key<String> PARENT = Metadata.Key.of("parentId", Metadata.ASCII_STRING_MARSHALLER);

    //调用成功了，待给你返回个状态code
    private static final Metadata.Key<String> CODE = Metadata.Key.of("code", Metadata.ASCII_STRING_MARSHALLER);




    @Override
    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
//        log.info(serverCall.getMethodDescriptor().getFullMethodName());
//        return serverCallHandler.startCall(serverCall, metadata);

        // 服务端从headers中获取到链路追踪参数
        String traceId = metadata.get(TRACE);
        String spanId = metadata.get(SPAN);
        String parentId = metadata.get(PARENT);
        // 构建当前进程的链路追踪数据并体现在日志中
//        Tracer.trace(traceId, spanId, parentId);
        log.info("local server start work");
        log.info("current traceId is: {}", traceId);
        log.info("current spanId is: {}", spanId);
        log.info("current parentId is: {}", parentId);

        return serverCallHandler.startCall(new ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(serverCall) {

            @Override
            public void sendHeaders(Metadata responseHeaders) {
                responseHeaders.put(CODE, "success");
                super.sendHeaders(responseHeaders);
            }

            @Override
            public void close(Status status, Metadata trailers) {
                super.close(status, trailers);
            }
        }, metadata);
    }

    private static class GrpcServerCall<M, R> extends ServerCall<M, R> {

        ServerCall<M, R> serverCall;

        @Override
        public void request(int numMessages) {

        }

        /**
         * 在发送响应消息之前发送响应头元数据
         */
        @Override
        public void sendHeaders(Metadata headers) {

        }

        /**
         * 发送响应消息
         */
        @Override
        public void sendMessage(R message) {

        }

        @Override
        public void close(Status status, Metadata trailers) {

        }

        /**
         * 当调用被取消并鼓励服务器中止处理以节省资源时返回 true，
         * 因为客户端将不会处理任何进一步的方法。
         */
        @Override
        public boolean isCancelled() {
            return serverCall.isCancelled();
        }

        @Override
        public MethodDescriptor<M, R> getMethodDescriptor() {
            return serverCall.getMethodDescriptor();
        }
    }
}
